# -*- coding: utf-8 -*-
# @Date：2024/7/22 03:41:52
# @Author：CJiaの青姝
# @FileName：user
# @Editor：PyCharm2024
# @Remark：
from typing import Any, List
from typing_extensions import Self

from auths.models import Users, UsersRole, Role
from data.models import DictType
from ninja import Router, Field, File, Query, Schema, ModelSchema
from ninja.files import UploadedFile
from ninja.pagination import paginate

from utils.cj_md5 import md5_encrypt
from utils.cj_ninja import CjFilters, MyPagination
from utils.cj_crud import create, batch_create, delete, batch_delete, update, condition, single
from utils.cj_export import export_data, repeat_data, deal_chinese_key
from utils.cj_response import SuccessResponse, ErrorResponse

router = Router()


class Filters(CjFilters):
    username: str = Field(None, description="用户名", alias='username')
    email: str = Field(None, description="邮箱", alias='email')
    name: str = Field(None, description="姓名", alias='name')
    mobile: str = Field(None, description="电话", alias='mobile')
    user_type: int = Field(None, description="用户类型", alias='user_type')

    class Config:
        title = "用户查询参数"


class UsersSchemaIn(ModelSchema):
    role: list = Field([], description="用户角色", alias='role')

    def validate(cls, value: Any) -> Self:
        if value.username == '' or value.username is None:
            return "用户名不能为空", 400
        elif value.name == '' or value.name is None:
            return "姓名不能为空", 400
        # 返回请求数据
        return value.dict(), 200

    def model_validate(
            cls,
            obj: Any,
            *,
            strict: bool | None = None,
            from_attributes: bool | None = None,
            context: Any | None = None,
    ) -> Self:
        if obj.username == '' or obj.username is None:
            return "用户名不能为空", 400
        elif obj.name == '' or obj.name is None:
            return "姓名不能为空", 400
        # 判断重复
        if Users.objects.filter(username=obj.username).exists():
            return "用户名已存在，请重新输入", 400
        if Users.objects.filter(email=obj.email).exists():
            return "邮箱已存在，请重新输入", 400
        # 返回请求数据
        return obj.dict(), 200

    class Config:
        title = "创建用户参数"
        model = Users
        model_exclude = ['id', 'creator', 'modifier', 'create_time', 'update_time',
                         'password', 'password_str']


class UsersSchemaOut(ModelSchema):
    key: int = Field(None, description="唯一标识符", alias='key')
    role: list = Field([], description="用户角色", alias='role')

    class Config:
        title = "用户对象实例"
        model = Users
        model_exclude = ['password', 'password_str']


@router.post("/user", response=UsersSchemaOut, summary="创建用户")
def create_user(request, data: UsersSchemaIn):
    """ 创建用户 """
    message, code = data.model_validate(data)
    if code == 400:
        return ErrorResponse(msg=message)
    roles = message['role']
    del message['role']
    # 调用新增方法
    result = create(request, Users, message)
    # 配置默认密码
    password = "123456"
    user = Users.objects.get(id=result['id'])
    user.password_str = password
    user.password = md5_encrypt(password)
    user.save()
    # 新增子表
    for role in roles:
        create(request, UsersRole, {'user_id': result['id'], 'role_id': role})
    # 返回结果
    return SuccessResponse(data=result, msg="新增成功")


@router.post("/user/export", summary="导入用户")
def export_role(request, file: UploadedFile = File(...)):
    # 字段关系
    field_relations = {
        "用户名": "username",
        "姓名": "name",
        "邮箱": "email",
        "电话": "mobile",
        "性别": "gender",
        "用户类型": "user_type",
    }
    # 检查字段
    check_list = ["用户名", "姓名"]
    # 调用公共导入方法
    export_result = export_data(request, file, check_list)
    # 重复字段
    repeat_filed = [
        {"name": "用户名", "field": "username", "model": "username"},
        {"name": "邮箱", "field": "email", "model": "email"},
    ]
    # 判断重复
    result = repeat_data(Users, export_result['success'], repeat_filed, False)
    # 处理一下数据
    for user in result['success']:
        user['性别'] = DictType.objects.get(name=user['性别']).value
        user['用户类型'] = DictType.objects.get(name=user['用户类型']).value
    # 处理中文key
    result = deal_chinese_key(result, field_relations)
    # 调用批量新增方法
    result_list = batch_create(request, Users, result['success'])
    users = Users.objects.bulk_create(result_list)
    # 默认创建用户角色
    for user in users:
        create(request, UsersRole, {'user_id': user.id, 'role_id': Role.objects.get(name="用户").id})
    message = f"成功导入{len(result_list)}条数据，失败信息{export_result['error'] + result['error']}"
    # 返回结果
    return SuccessResponse(data=result['success'], msg=message)


@router.delete("/user/{user_id}", response=UsersSchemaOut, summary="删除用户")
def delete_user(request, user_id: int):
    """ 删除用户 """
    # 调用删除方法
    result, code = delete(Users, user_id)
    if code != 200:
        return ErrorResponse(code=code, msg=result)
    # 删除关联角色
    for role_id in UsersRole.objects.filter(user_id=user_id).values_list('id', flat=True):
        delete(UsersRole, role_id)
    # 返回结果
    return SuccessResponse(data=result, msg="删除成功")


@router.delete("/user/batch/del", summary="批量删除用户")
def batch_delete_user(request, ids: List[int]):
    """ 批量删除用户 """
    # 调用批量删除方法
    result = batch_delete(request, Users, ids)
    # 返回结果
    return SuccessResponse(data=result, msg="批量删除成功")


@router.put("/user/{user_id}", summary="更新用户")
def update_user(request, user_id: int, data: UsersSchemaIn):
    """ 更新用户 """
    message, code = data.validate(data)
    if code == 400:
        return ErrorResponse(msg=message)
    # 判断重复
    if Users.objects.filter(username=message['username']).exists():
        if Users.objects.get(username=message['username']).id != user_id:
            return ErrorResponse(msg="用户名已存在，请重新输入")
    if Users.objects.filter(name=message['name']).exists():
        if Users.objects.get(name=message['name']).id != user_id:
            return ErrorResponse(msg="姓名已存在，请重新输入")
    roles = message['role']
    del message['role']
    # 调用修改方法
    result = update(request, Users, message, user_id)
    # 删除关联角色
    for role_id in UsersRole.objects.filter(user_id=user_id).values_list('id', flat=True):
        delete(UsersRole, role_id)
    # 新增子表
    for role in roles:
        create(request, UsersRole, {'user_id': user_id, 'role_id': role})
    # 返回结果
    return SuccessResponse(data=result, msg="更新成功")


@router.get("/user", response=List[UsersSchemaOut], auth=None, summary="获取分页用户列表")
@paginate(MyPagination)
def list_user(request, filters: Filters = Query(...)):
    """ 获取分页用户列表 """
    # 调用分页方法
    result = condition(request, Users, filters)
    # 返回结果
    return result


@router.get("/user/{user_id}", response=UsersSchemaOut, summary="获取用户")
def get_user(request, user_id: int):
    """ 获取用户 """
    # 调用根据id获取指定对象方法
    result = single(request, Users, id=user_id)
    # 获取用户所属角色
    result['role'] = list(UsersRole.objects.filter(user_id=user_id).values_list('role_id', flat=True))
    # 返回结果
    return SuccessResponse(data=result)
